package com.wxq.product.aop;

import com.wxq.product.annotation.WatchTimeAnnotation;
import org.springframework.util.StopWatch;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @author Jim
 * @date 1:17 下午 2022/4/5
 * @description
 * @email:huwmz04153277@126.com
 */
@Aspect
@Component
public class MyAop {


    final static Logger LOGGER = LoggerFactory.getLogger(MyAop.class);

    @Pointcut("@annotation(com.wxq.product.annotation.WatchTimeAnnotation)")
    public void watchTimeAspectPointCutWithAnnos() {

    }

    @Around("watchTimeAspectPointCutWithAnnos()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) point.getSignature();

        // Get intercepted method details
        String className = methodSignature.getDeclaringType().getSimpleName();
        String methodName = methodSignature.getName();

        String value = "";
        String desc = "";
        int level = 0;
        // 获取运行方法调用的此注解
        WatchTimeAnnotation timeAnnotation = methodSignature.getMethod().getAnnotation(WatchTimeAnnotation.class);
        if (null != timeAnnotation) {
            value = timeAnnotation.name();
            desc = timeAnnotation.desc();
            level = timeAnnotation.level();
        }

        final StopWatch stopWatch = new StopWatch();

        //Measure method execution time
        stopWatch.start();
        //执行任务
        Object result = point.proceed();
        stopWatch.stop();

        //Log method execution time
        if (level >= 5) {
            LOGGER.warn("【执行时间-warning】 {}.{}(value={},desc={})::{} ms",
                    className, methodName,
                    value, desc,
                    stopWatch.getTotalTimeMillis());
        } else if (level > 0 && level < 5) {
            LOGGER.info("【执行时间】 {}.{}(value={},desc={})::{} ms",
                    className, methodName,
                    value, desc,
                    stopWatch.getTotalTimeMillis());
        } else {
            LOGGER.info("不打印日志");
        }

        return result;
    }


    @Pointcut("execution (* com.wxq.product.service.impl.AttrGroupServiceImpl.*(..))")
    public void test() {

    }

    @Before("test()")
    public void beforeAdvice() {
        System.out.println("beforeAdvice...");
    }

    @After("test()")
    public void afterAdvice() {
        System.out.println("afterAdvice...");
    }

    @Around("test()")
    public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
        System.out.println("before");
        try {
            System.err.println(proceedingJoinPoint.getArgs());
        } catch (Throwable t) {
            t.printStackTrace();
        }
        System.out.println("after");
    }

/*    @Around(value = "@annotation(com.joinf.dbutils.commons.annotation.MonitorExecTime)")
    public Object execTimeAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getDeclaringTypeName() + "." + signature.getName();
        MonitorMethodExecTime monitor = signature.getMethod().getAnnotation(MonitorExecTime.class);
        try {
            Object[] args = joinPoint.getArgs();
            return joinPoint.proceed(args);
        } finally {
            printExecTime(methodName, startTime, System.currentTimeMillis(), monitor);
        }
    }

    *//**
     * 打印执行时间
     *
     * @param methodName         完整方法名
     * @param startTime          开始时间
     * @param endTime            结束时间
     * @param monitorExecTime 注解
     * @return void
     * @author lyf
     * @date 2020-11-13 9:29
     *//*
    private void printExecTime(String methodName, long startTime, long endTime, MonitorExecTime monitorExecTime) {
        long execTime = endTime - startTime;
        String template = "%s -- %s -- 耗时%d ms";
        String printInfo = String.format(template, monitorExecTime.desc(), methodName, execTime);
        if (execTime > API_EXEC_TIME_PRINT_START) {
            log.debug(printInfo);
        }

        if (execTime > API_EXEC_TIME_MONITOR_START) {
            FeishuUtil.sendRemind(printInfo);
        }
    }*/
}
